package com.qingyun.web.security.provider;

import cn.hutool.core.util.ObjectUtil;
import com.qingyun.common.core.domain.model.TiktokUser;
import com.qingyun.common.utils.StringUtils;
import com.qingyun.security.enums.App;
import com.qingyun.security.model.tiktok.TikTokLoginUser;
import com.qingyun.security.provider.AbstractUserDetailsAuthenticationProvider;
import com.qingyun.tiktok.basis.response.user.UserOpenInfoRes;
import com.qingyun.tiktok.basis.service.interfaces.DyBasisService;
import com.qingyun.tiktok.common.enums.ApiPlatform;
import com.qingyun.tiktok.common.response.auth.AccessTokenRes;
import com.qingyun.tiktok.service.ITiktokUserService;
import com.qingyun.web.security.service.UserDetailsServiceImpl;
import com.qingyun.web.security.token.TikTokAuthenticationToken;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import ma.glasnost.orika.MapperFacade;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

/**
 * @Classname TikTokAppAuthenticationProvider
 * @Author dyh
 * @Date 2021/9/8 17:28
 */
@Component
@AllArgsConstructor
@Slf4j
public class TikTokAppAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {

    private UserDetailsServiceImpl userDetailsService;

    private ITiktokUserService tiktokUserService;

    private DyBasisService dyBasisService;

    private MapperFacade mapperFacade;

	@Override
	protected void additionalAuthenticationChecks(UserDetails userDetails, Authentication authentication) {
		TikTokLoginUser tikTokLoginUser=(TikTokLoginUser)userDetails;
		String openId = tikTokLoginUser.getOpenId();
		TiktokUser tikTokUser = tiktokUserService.lambdaQuery().eq(TiktokUser::getOpenId, openId).one();
		if(ObjectUtil.isNull(tikTokUser)){
			UserOpenInfoRes.GetUserOpenInfoResData userOpenInfo = dyBasisService.getUserManagerService().getUserOpenInfo(openId, ApiPlatform.DOU_YIN);
			tikTokUser = new TiktokUser();
			mapperFacade.map(userOpenInfo,tikTokUser);
			tiktokUserService.save(tikTokUser);
			tikTokLoginUser.setOneLogin(true);
		}else{
			tikTokLoginUser.setOneLogin(false);
		}
	}

	@Override
	protected Authentication createSuccessAuthentication(Authentication authentication, UserDetails user) {
		TikTokLoginUser tikTokLoginUser=(TikTokLoginUser)user;
		String openId = tikTokLoginUser.getOpenId();
		TikTokLoginUser userDetails = (TikTokLoginUser)userDetailsService.loadUserByUsername(openId);
		//交换登录次数状态
		userDetails.setOneLogin(tikTokLoginUser.isOneLogin());
		userDetails.setOpenId(openId);
		TikTokAuthenticationToken tikTokAuthenticationToken = new TikTokAuthenticationToken(userDetails,"null");
		tikTokAuthenticationToken.setDetails(authentication.getDetails());
		return tikTokAuthenticationToken;
	}

	@Override
	protected App getAppInfo() {
		return null;
	}

	@Override
	protected UserDetails retrieveUser(String username, Authentication authentication) throws AuthenticationException {
		TikTokAuthenticationToken tikTokAuthenticationToken= (TikTokAuthenticationToken) authentication;
		String code = tikTokAuthenticationToken.getCode();
		if(StringUtils.isBlank(code)){
			log.debug("code为空");
			throw new BadCredentialsException("登陆code不能为空");
		}
		AccessTokenRes.AccessTokenResData accessTokenResData = dyBasisService.getAuth2Service().authAccessToken(code, ApiPlatform.DOU_YIN);
		return new TikTokLoginUser(accessTokenResData.getOpenId());
	}

	@Override
	public boolean supports(Class<?> aClass) {
		return TikTokAuthenticationToken.class.isAssignableFrom(aClass);
	}
}
